import { ref, onUnmounted, watch } from "vue";
import * as Sentry from "@sentry/browser";

// 性能监控配置
interface PerformanceConfig {
  fpsSampleInterval?: number; // FPS采样间隔(ms)，默认1000ms
  lowFpsThreshold?: number; // 低帧率阈值，默认15FPS
  maxFpsHistory?: number; // 最大FPS历史记录数量，默认30
}

// 性能数据
interface PerformanceData {
  mapFps: number; // 当前帧率
  recentFps: number[]; // 最近FPS记录
  mapLoadTime: number; // 地图加载时间(ms)
  markerCount: number; // 标记点数量
  renderTime: number; // 单次渲染时间(ms)
  isLowPerformance: boolean; // 是否处于低性能状态
}

export function useMapPerformance(config: PerformanceConfig = {}) {
  // 配置默认值
  const fpsSampleInterval = config.fpsSampleInterval || 1000;
  const lowFpsThreshold = config.lowFpsThreshold || 15;
  const maxFpsHistory = config.maxFpsHistory || 30;

  // 性能状态
  const performanceData = ref<PerformanceData>({
    mapFps: 0,
    recentFps: [],
    mapLoadTime: 0,
    markerCount: 0,
    renderTime: 0,
    isLowPerformance: false
  });

  // 内部状态
  const isMonitoring = ref(false);
  let frameCount = 0;
  let lastFpsCheckTime = 0;
  let animationFrameId: number | null = null;
  let renderStartTime = 0;

  // 更新标记点数量
  const updateMarkerCount = (count: number) => {
    performanceData.value.markerCount = count;

    // 标记点过多时记录警告
    if (count > 1000) {
      Sentry.addBreadcrumb({
        message: "Large number of markers",
        category: "performance",
        level: "warning",
        data: { markerCount: count }
      });
    }
  };

  // 记录地图加载时间
  const recordMapLoadTime = (startTime: number) => {
    performanceData.value.mapLoadTime = Math.round(
      performance.now() - startTime
    );

    // 加载时间过长时记录警告
    if (performanceData.value.mapLoadTime > 3000) {
      Sentry.addBreadcrumb({
        message: "Slow map loading",
        category: "performance",
        level: "warning",
        data: { loadTime: performanceData.value.mapLoadTime }
      });
    }
  };

  // 记录单次渲染时间
  const recordRenderTime = () => {
    if (renderStartTime) {
      const endTime = performance.now();
      performanceData.value.renderTime = Math.round(endTime - renderStartTime);

      // 渲染时间过长时记录警告
      if (performanceData.value.renderTime > 50) {
        Sentry.addBreadcrumb({
          message: "Slow render time",
          category: "performance",
          level: "warning",
          data: { renderTime: performanceData.value.renderTime }
        });
      }
    }

    // 重置渲染计时器
    renderStartTime = performance.now();
  };

  // FPS监控循环
  const fpsMonitoringLoop = () => {
    if (!isMonitoring.value) return;

    const now = performance.now();
    frameCount++;

    // 计算FPS
    if (now - lastFpsCheckTime >= fpsSampleInterval) {
      const fps = Math.round((frameCount * 1000) / (now - lastFpsCheckTime));

      // 更新FPS数据
      performanceData.value.mapFps = fps;
      performanceData.value.recentFps.push(fps);

      // 限制历史记录长度
      if (performanceData.value.recentFps.length > maxFpsHistory) {
        performanceData.value.recentFps.shift();
      }

      // 检查是否低性能
      performanceData.value.isLowPerformance = fps < lowFpsThreshold;

      // 低帧率报警
      if (fps < lowFpsThreshold) {
        Sentry.addBreadcrumb({
          message: "Low map FPS",
          category: "performance",
          level: "warning",
          data: {
            fps,
            markerCount: performanceData.value.markerCount
          }
        });
      }

      // 重置计数器
      frameCount = 0;
      lastFpsCheckTime = now;
    }

    // 继续监控循环
    animationFrameId = requestAnimationFrame(fpsMonitoringLoop);
  };

  // 开始性能监控
  const startMonitoring = () => {
    if (isMonitoring.value) return;

    isMonitoring.value = true;
    frameCount = 0;
    lastFpsCheckTime = performance.now();
    renderStartTime = performance.now();

    // 启动监控循环
    fpsMonitoringLoop();
  };

  // 停止性能监控
  const stopMonitoring = () => {
    isMonitoring.value = false;
    if (animationFrameId) {
      cancelAnimationFrame(animationFrameId);
      animationFrameId = null;
    }
  };

  // 组件卸载时自动停止监控
  onUnmounted(() => {
    stopMonitoring();
  });

  // 暴露给外部的方法和状态
  return {
    performanceData,
    updateMarkerCount,
    recordMapLoadTime,
    recordRenderTime, // 供外部调用，记录地图渲染时间
    startMonitoring,
    stopMonitoring
  };
}
